package vip.learning.order.rpc.rest;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import vip.learning.order.rpc.entity.StoreOrder;
import vip.learning.order.rpc.feign.AccountFeignClient;
import vip.learning.order.rpc.feign.ProductFeignClient;
import vip.learning.order.rpc.feign.WareFeignClient;
import vip.learning.order.rpc.rest.vo.OrderVo;
import vip.learning.order.rpc.service.OrderService;
import vip.learning.order.rpc.utils.HttpResult;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;


/**
 * @Description:
 * @Created: description
 * @author: hubin
 * @createTime: 2020-06-19 11:21
 **/

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;


    @Autowired
    private ProductFeignClient feignClient;

    @RequestMapping("/rpc/{id}")
    public HttpResult findOne(@PathVariable Long id, HttpServletRequest request){

        String header = request.getHeader("X-Request-Foo");

        return HttpResult.ok("find order by id .....");

    }

    /**
     * @Description: 根据id查询商品信息
     * @Author: hubin
     * @CreateDate: 2021/2/4 16:52
     * @UpdateUser: hubin
     * @UpdateDate: 2021/2/4 16:52
     * @UpdateRemark: 修改内容
     * @Version: 1.0
     */
    @RequestMapping("/sku/{skuId}")
    StoreOrder findStoreProductById(@PathVariable("skuId") Long skuId){
        // 查询商品信息
        StoreOrder order = new StoreOrder();
        order.setRealName("real order...");
        return order;
    }

    @RequestMapping("/price/{skuId}")
    BigDecimal getPrice(@PathVariable("skuId") Integer skuId){
        //查询商品价格
        return BigDecimal.ZERO;
    }


    @RequestMapping("/test-a")
    public String testA(){
        return "test-a";
    }

    @RequestMapping("/test-b")
    public String testB(){
        return "test-b";
    }


    @RequestMapping("/test-hot")
    public String testHot(@RequestParam(required = false) String a , @RequestParam(required = false) String b){
        return a + "test-b" + b;
    }


    @RequestMapping("/rpc/pro")
    public String getPro(){
        String pro = feignClient.getPro();
        return pro;
    }

    @RequestMapping("flowLimit1")
    public String flowLimit1(){
        orderService.backendServer();
        return "this is flow limit method! flowLimit1";
    }

    @RequestMapping("flowLimit2")
    public String flowLimit2() throws InterruptedException {
        orderService.backendServer();
        return "this is flow limit method! flowLimit2";
    }


    /**
     * @Description: 方法描述
     * @Author: hubin
     * @CreateDate: 2022/1/13 21:35
     * @UpdateUser: hubin
     * @UpdateDate: 2022/1/13 21:35
     * @UpdateRemark: 测试降级
     * @Version: 1.0
     */
    @RequestMapping("dwongrade")
    public String downgrade() throws InterruptedException {

        TimeUnit.SECONDS.sleep(1);

        return "降级test";
    }


    @RequestMapping("exTest")
    public String exTest() throws InterruptedException {
        // 模拟异常
        int a = 10/0;
        return "降级test";
    }


   /* @RequestMapping("test-add-flow-rule")
    public String testRule(){
        this.initFlowQpsRule();
        return "test-add-flow-rule success";
    }*/

/*
    private void initFlowQpsRule(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("/order/test-a");
        rule.setCount(20);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }


    *//**
     * @Description: 方法描述
     * @Author: hubin
     * @CreateDate: 2022/1/13 22:17
     * @UpdateUser: hubin
     * @UpdateDate: 2022/1/13 22:17
     * @UpdateRemark: SphU的方式定义限流，降级，熔断
     * @Version: 1.0
     *//*
    @RequestMapping("test-sentinel-api")
    public String testSentinelAPI(@RequestParam(required = false) String a){
        String resourceName = "test-sentinel";
        //ContextUtil.enter(resourceName,"test");
        Entry entry = null;
        try {
            // 定义被限流，降级，熔断资源
            entry =  SphU.entry(resourceName);
            // 业务代码
            // 被保护的业务逻辑
            if(StringUtils.isBlank(a)){
                throw new IllegalArgumentException("a参数不能为空");
            }

            return  a;

        } catch (BlockException e) {
            log.warn("限流了，或者降级了",e);
            e.printStackTrace();
            return "限流了，或者降级了";
        }catch (Exception e2){
            Tracer.trace(e2);
            return "参数非法";
        }finally {
            if(entry!= null){
                entry.exit();
            }
        }
    }


    // @SentinelResource实现流控，降级，熔断
    @RequestMapping("test-anno")
    @SentinelResource(value = "testAnno",blockHandler = "blockHandlerTest")
    public String testAnno(String a){
        throw new RuntimeException("exec program failed ....");
    }


    public String blockHandlerTest(String a,BlockException e){
        log.warn("限流了，或者降级了",e);
        return "限流了，或者降级了";
    }


    @RequestMapping("log")
    public String showLog(){

        log.error("this is a test log");

        return "show log";
    }*/




    @RequestMapping("/create/v1")
    public OrderVo createOrder(){
        String userId = "1";
        String commodityCode = "1";
        Integer count = 2;
        OrderVo orderVo = orderService.createOrder(userId,commodityCode,count);
        return orderVo;
    }



}